package org.dromara.job.processors;

import cn.hutool.core.collection.CollUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.patrol.api.RemotePatrolSubtaskCommonService;
import org.dromara.patrol.api.domain.bo.RemotePatrolSubtaskBo;
import org.dromara.patrol.api.domain.vo.RemotePatrolSubtaskVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import tech.powerjob.client.PowerJobClient;
import tech.powerjob.common.model.LifeCycle;
import tech.powerjob.common.request.http.SaveJobInfoRequest;
import tech.powerjob.common.response.ResultDTO;
import tech.powerjob.worker.core.processor.ProcessResult;
import tech.powerjob.worker.core.processor.TaskContext;
import tech.powerjob.worker.core.processor.sdk.BasicProcessor;

import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

import static tech.powerjob.common.enums.ExecuteType.STANDALONE;
import static tech.powerjob.common.enums.ProcessorType.BUILT_IN;
import static tech.powerjob.common.enums.TimeExpressionType.*;

/**
 * 巡店管理-创建巡店子任务
 */
@Slf4j
@Component
public class PatrolTaskCircleCreateProcessor implements BasicProcessor {

    @DubboReference(timeout = 10000)
    private RemotePatrolSubtaskCommonService remotePatrolSubtaskCommonService;

    @Autowired
    private PowerJobClient powerJobClient;

    @Override
    public ProcessResult process(TaskContext taskContext) throws Exception {
        log.info("PatrolTaskCircleCreateProcessor============>创建非主子任务开始执行啦！！！taskId={}", taskContext.getJobParams());
        // 通过主任务，创建新的非主子任务
        RemotePatrolSubtaskBo remotePatrolSubtaskBo = getRemotePatrolSubtaskBo(taskContext);
        List<RemotePatrolSubtaskVo> vo = remotePatrolSubtaskCommonService.createNonMainPatrolSubtask(remotePatrolSubtaskBo);
        if (vo == null) {
            return new ProcessResult(false, "PatrolTaskCircleCreateProcessor 运行失败！！！");
        }
        log.info("PatrolTaskCircleCreateProcessor============>循环创建子任务成功啦！！！");
        // 创建状态刷新定时任务，为什么要每个任务都创建定时任务呢？考虑到按天、周、月循环，时间自定义，
        // 且每个任务都有不同的执行时间，所以需要单独创建定时任务
        AtomicReference<Boolean> flag = new AtomicReference<>(true);
        vo.stream().filter(item -> item.getId() != null).forEach(item -> {
            if (item.getExecuteEndTime() >= System.currentTimeMillis() + 3000) {
                SaveJobInfoRequest createRequest = getSaveJobInfoRequest(item);
                ResultDTO<Long> result = powerJobClient.saveJob(createRequest);
                if (!result.isSuccess()) {
                    log.error("PatrolTaskCircleCreateProcessor============>创建子任务状态刷新任务失败啦{}！！！", item.getId());
                    flag.set(false);
                }
                item.setCycleTaskId(result.getData());
            }
        });
        if (flag.get() && CollUtil.isEmpty(vo) || remotePatrolSubtaskCommonService.updateCyclicTaskById(vo)) {
            return new ProcessResult(true, "PatrolTaskCircleCreateProcessor 运行成功啦！！！");
        } else {
            return new ProcessResult(false, "PatrolTaskCircleCreateProcessor 运行失败！！！");
        }
    }

    private SaveJobInfoRequest getSaveJobInfoRequest(RemotePatrolSubtaskVo vo) {
        SaveJobInfoRequest request = new SaveJobInfoRequest();
        request.setMinCpuCores(0);
        request.setMinDiskSpace(0);
        request.setMinMemorySpace(0);
        request.setJobName(vo.getName() + "_子任务状态刷新任务");
        request.setJobParams(vo.getId() + "");
        request.setExecuteType(STANDALONE);
        request.setTimeExpressionType(CRON);
        // 采用cron表达式 精准调度，如：0 15 23 15 6 ? 2022-2022 = 2022-06-15 23:15:00
        request.setTimeExpression(StringUtils.convertTimeStrToCron(vo.getEndTimeStr()));
        LifeCycle lifeCycle = new LifeCycle();
        lifeCycle.setStart(vo.getExecuteStartTime());
        lifeCycle.setEnd(vo.getExecuteEndTime());
        request.setLifeCycle(lifeCycle);
        request.setProcessorType(BUILT_IN);
        request.setConcurrency(Integer.MAX_VALUE);
        request.setProcessorInfo("org.dromara.job.processors.PatrolTaskCheckUnFinishedStatusProcessor");
        return request;
    }
    private RemotePatrolSubtaskBo getRemotePatrolSubtaskBo(TaskContext taskContext) {
        long currentTime = System.currentTimeMillis();
        String jobParams = taskContext.getJobParams();
        RemotePatrolSubtaskBo remotePatrolSubtaskBo = new RemotePatrolSubtaskBo();
        remotePatrolSubtaskBo.setCycleTaskId(taskContext.getJobId());
        remotePatrolSubtaskBo.setCurrentTime(currentTime);
        remotePatrolSubtaskBo.setTaskId(Long.valueOf(jobParams));
        remotePatrolSubtaskBo.setTaskName(taskContext.getTaskName());
        remotePatrolSubtaskBo.setDateStr(DateUtils.dateTime(new Date(currentTime)));
        return remotePatrolSubtaskBo;
    }
}
